package com.sxkj.web.controller.wechat;

import com.github.sd4324530.fastweixin.api.OauthAPI;
import com.github.sd4324530.fastweixin.api.config.ApiConfig;
import com.github.sd4324530.fastweixin.api.enums.OauthScope;
import com.github.sd4324530.fastweixin.api.response.GetUserInfoResponse;
import com.github.sd4324530.fastweixin.api.response.OauthGetTokenResponse;
import com.sxkj.common.utils.StringUtils;
import com.sxkj.common.wechat.MyOauthAPI;
import com.sxkj.entity.entity.wechat.WechatUser;
import com.sxkj.service.redis.RedisService;
import com.sxkj.service.wechat.WechatUserService;
import com.sxkj.web.config.WxPayConfig;
import io.swagger.annotations.Api;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 微信菜单操作
 *
 * @author Zhang xingliang
 */
@Api(tags = "WechatOauthController", description = "微信授权获取微信用户信息")
@RestController
@RequestMapping("/wechat")
public class WechatOauthController {

    @Autowired
    private WxPayConfig wxPayConfig;
    @Autowired
    private RedisService redisService;
    @Autowired
    private WechatUserService wechatUserService;

    /**
     * 微信oauth认证连接 静默授权
     * 微信重新向页面，
     * 当Code为空时调用 获取code 再重定向到当前连接 通过code获取token ，然后用这个code获得access token
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/authorization", method = RequestMethod.GET)
    public void authorization(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ApiConfig config = new ApiConfig(wxPayConfig.getAppID(), wxPayConfig.getAppSecret());
        String code = request.getParameter("code");
        if (code == null) {
            String url = request.getRequestURL().toString();
            String query = request.getQueryString() != null ? "?" + request.getQueryString().toString() : "";
            response.sendRedirect(new OauthAPI(config).getOauthPageUrl(url + query, OauthScope.SNSAPI_BASE, "1"));
            return;
        }
        MyOauthAPI oauthAPI = new MyOauthAPI(config);
        OauthGetTokenResponse token = oauthAPI.getToken(code);
        String openid = token.getOpenid();
        String redirect = request.getParameter("redirecturl");
        response.sendRedirect(wxPayConfig.getFrontRedirect() + redirect == null ? "" : redirect + "?openid=" + openid);
    }

    /**
     * 微信oauth认证连接 需要用户授权同意 获取微信用户头像
     * 微信重新向页面，微信菜单指向本地址
     * 当Code为空时调用 获取code 再重定向到当前连接 通过code获取token ，然后用这个code获得access token
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/oauth", method = RequestMethod.GET)
    public void auth(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ApiConfig config = new ApiConfig(wxPayConfig.getAppID(), wxPayConfig.getAppSecret());
        String code = request.getParameter("code");
        if (code == null) {
            String url = request.getRequestURL().toString();
            String query = request.getQueryString() != null ? "?" + request.getQueryString().toString() : "";
            response.sendRedirect(new OauthAPI(config).getOauthPageUrl(url + query, OauthScope.SNSAPI_USERINFO, "1"));
            return;
        }
        MyOauthAPI oauthAPI = new MyOauthAPI(config);
        OauthGetTokenResponse token = oauthAPI.getToken(code);
        String openid = token.getOpenid();
        String status = redisService.get(token.getOpenid());
        if (status != null) {//redis缓存中存在 todo设置缓存过期时间

        } else {
            redisService.set(openid, "1");
            WechatUser wechatUser = wechatUserService.getWechatUserByOpenid(openid);
            GetUserInfoResponse wxMpUser = oauthAPI.getUserInfo(token.getAccessToken(), openid);
            if (wechatUser == null) {
                save(wxMpUser);
            } else {
                //更新昵称
                if (StringUtils.isBlank(wechatUser.getNickName())) {
                    update(wechatUser, wxMpUser);
                }
            }
        }
        String redirect = request.getParameter("redirecturl");
        response.sendRedirect(wxPayConfig.getFrontRedirect() + redirect == null ? "" : redirect + "?openid=" + openid);
    }

    private boolean save(GetUserInfoResponse wxMpUser) {
        try {
            WechatUser wechatUser = new WechatUser();
            wechatUser.setOpenId(wxMpUser.getOpenid());
            wechatUser.setHeadImgUrl(wxMpUser.getHeadimgurl());
            String nickname = wxMpUser.getNickname();
            nickname = Base64.encodeBase64String(nickname.getBytes("UTF-8"));
            wechatUser.setNickName(nickname);
            wechatUser.setCity(wxMpUser.getCity());
            wechatUser.setCountry(wxMpUser.getCountry());
            wechatUser.setProvince(wxMpUser.getProvince());
            wechatUser.setSex(wxMpUser.getSex());
            wechatUser.setSubscribe(wxMpUser.getSubscribe());
            wechatUserService.save(wechatUser);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private boolean update(WechatUser wechatUser, GetUserInfoResponse wxMpUser) {
        try {
            wechatUser.setHeadImgUrl(wxMpUser.getHeadimgurl());
            String nickname = wxMpUser.getNickname();
            nickname = Base64.encodeBase64String(nickname.getBytes("UTF-8"));
            wechatUser.setNickName(nickname);
            wechatUser.setCity(wxMpUser.getCity());
            wechatUser.setCountry(wxMpUser.getCountry());
            wechatUser.setProvince(wxMpUser.getProvince());
            wechatUser.setSex(wxMpUser.getSex());
            wechatUser.setSubscribe(wxMpUser.getSubscribe());
            wechatUserService.save(wechatUser);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
